package user

import (
	"context"
	"fmt"
	partner "gitee.com/binny_w/gin-partner"
	"gitee.com/binny_w/gin_starter/core"
	"gitee.com/binny_w/gin_starter/model/rsa"
	verify "gitee.com/binny_w/gin_starter/model/slider_verify"
	"gitee.com/binny_w/go-util"
	util2 "gitee.com/binny_w/go-util/v2"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"time"
)

func login(c *gin.Context) {
	if err := verify.CheckCode(c.PostForm("verify_id"), c.PostForm("verify_code"), c.Request.UserAgent(), c.ClientIP()); err != nil {
		partner.WriteJsonError(c, 411, "滑动验证错误，请确认")
		return
	}
	password, err := rsa.Decode(c.PostForm("password"))
	if err != nil {
		partner.WriteJsonError(c, 412, err.Error())
		return
	}
	if len(password) < 6 || len(password) > 20 {
		partner.WriteJsonError(c, 412, ErrWrongPassSize.Error())
		return
	}
	sql := fmt.Sprintf("select `id`, `pasd`, `role` from `%s` where `name` = ? and `deleted_at` = 0 limit 1", MdlUser.Table.Name)
	var id uint64
	var password1, role string
	name := c.PostForm("name")
	if err = MdlUser.Table.SelectWalk(c, func(ctx context.Context, row *util2.MysqlRow) error {
		id = uint64(row.ToInt64("id"))
		password1 = row.ToStr("pasd")
		role = correctRole(id, row.ToStr("role"), true)
		return nil
	}, sql, name); err != nil {
		partner.WriteJsonError(c, 413, "用户不存在")
		return
	}
	if id == 0 || !util.StrCheckPass(password, password1) {
		partner.WriteJsonError(c, 414, "用户名或密码错误")
		return
	}
	token := ""
	timeNow := time.Now()
	if token, err = jwt.NewWithClaims(jwt.SigningMethodHS256, &core.JwtUserClaims{
		Id:   id,
		Name: name,
		Role: role,
		IP:   c.ClientIP(),
		UA:   c.Request.UserAgent(),
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(timeNow.Add(15 * 24 * time.Hour)),
			IssuedAt:  jwt.NewNumericDate(timeNow),
		},
	}).SignedString([]byte(core.Config.GetString("jwt-key"))); err != nil {
		partner.WriteJsonError(c, 415, err.Error())
		return
	}
	defer func() {
		ip := c.ClientIP()
		region, _ := core.Ip2region.Search(ip)
		_, _ = MdlUser.Table.UpdateById(c, &util2.MysqlRow{
			"last_login":  timeNow.Unix(),
			"last_ip":     ip,
			"last_region": region,
		}, id)
	}()
	partner.WriteJsonSuccess(c, gin.H{
		"id":    id,
		"name":  name,
		"role":  role,
		"token": token,
	})
}
